%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% read2DArrayFromFile.m
% setLogWritingFunctHandle.m
% write2DArrayToFile.m
% writeToLogFile.m
%
%==========================================================================

%==========================================================================
% The function "visualizeOverlaps" visualizes the overlaps between the
% consecutive signals and any related characteristics.
% INPUT: "signalsToShowArr" is a 2D array whose columns hold the individual
% uncalibrated signals to be used in the visualization of the overlaps.
% They come in pairs of consecutive signals. For example, the first and the
% second columns are the signals coming from two consecutive frames, the
% third and the fourth columns are another pair of signals coming from two
% consecutive frames, etc.
% "calibSignalsArr" is a 2D array whose columns hold all individual
% calibrated signals.
% "leftSamplesToIgnore" is the number of samples removed at the left end of
% the uncalibrated signals in the process of computing the calibrated
% signals.
% "rightSamplesToIgnore" is the number of samples removed at the right end
% of the uncalibrated signals in the process of computing the calibrated
% signals.
% "overlapMethodStrCellArr" is a cell vector whose cells hold strings
% specifying different methods used for computing the overlaps -
% sound-based (Snd), image-based (Img), sound-based image-corrected
% (Snd_ImgCorr).
% "overlapArrCellArr" is a cell vector of the same size as the previous
% cell array. Its cells are column vectors holding the amounts of overlap
% between every two consecutive signals (or images) computed using
% different methods. Each column vector's length is one less than the
% number of all given signals.
% "minDiffArrCellArr" is a cell vector of the same size as the previous two
% cell array. Its cells are column vectors of the same length as the column
% vectors storing the overlaps. It holds the relative average absolute
% difference between the overlapping portions of every two consecutive
% signals (or images).
% "numSignalsPerMask" is an optional, positive, odd integer specifying the
% number of consecutive signals to be used in the construction of each
% calibration mask.
% "numSmoothings" is a non-negative integer specifying the number of
% smoothing passes to be applied to the raw average of the given signals.
% "movingAveSpan" is a positive odd integer specifying the span of the
% stencil to be used for moving average smoothing of the average signal.
% "signalToShowIndArr" is a column vector specifying the indices of the
% signals which are to be visualized along with their calibrated versions.
% "writeToLogFunctHandle" is an optional function handle which writes to a
% fixed log text file if keeping a log is requested, or does nothing
% otherwise.
% OUTPUT: None.
%==========================================================================
function visualizeOverlaps(signalsToShowArr, calibSignalsArr, ...
    leftSamplesToIgnore, rightSamplesToIgnore, overlapMethodStrCellArr, ...
    overlapArrCellArr, minDiffArrCellArr, numSignalsPerMask, ...
    numSmoothings, movingAveSpan, signalToShowIndArr, writeToLogFunctHandle)

if (nargin < 12)
    writeToLogFunctHandle = @(x) '';
end

% Use the existing global variables to determine whether visualization is
% required, and what common prefix and file extension are to be used for
% the names of the image files saving snapshots of figures.
global globalDoVisualize globalShotFileNamePrefix globalShotFileExt
if (globalDoVisualize ~= true)
    return;
else
    shotFileNamePrefix = globalShotFileNamePrefix;
    shotFileExt = globalShotFileExt;
end

% Compose the current common prefix.
commonPrefix = [shotFileNamePrefix 'Range' num2str(numSignalsPerMask) ...
    '_Sweeps' num2str(numSmoothings) '_Span' num2str(movingAveSpan)];

% Get the common length of the signals.
signalLength = size(signalsToShowArr, 1);

% Check if legitimate values are specified for the number of samples
% removed at the two ends of the signals.
if ( (isnumeric(leftSamplesToIgnore) == false)||(leftSamplesToIgnore < 0)||(leftSamplesToIgnore > signalLength) )
    leftSamplesToIgnore = 0;
end
if ( (isnumeric(rightSamplesToIgnore) == false)||(rightSamplesToIgnore < 0)||(rightSamplesToIgnore > (signalLength - leftSamplesToIgnore)) )
    rightSamplesToIgnore = 0;
end

% Allocate memory for the title strings.
titleStrCellArr = cell(size(overlapMethodStrCellArr));

for k = 1:numel(overlapMethodStrCellArr)
    
    % Get the current data.
    overlapMethodStr = overlapMethodStrCellArr{k};
    overlapArr = overlapArrCellArr{k} + leftSamplesToIgnore + rightSamplesToIgnore;
    minDiffArr = minDiffArrCellArr{k};
    if (strcmpi(overlapMethodStr, 'Snd') == true)
        titleStr = 'Sound-based';
    elseif (strcmpi(overlapMethodStr, 'Img') == true)
        titleStr = 'Image-based';
    elseif (strcmpi(overlapMethodStr, 'Snd_ImgCorr') == true)
        titleStr = 'Sound-based image-corrected';
    end
    titleStrCellArr{k} = titleStr;
    
    % Write the overlaps to a text file.
    shotFileName = [commonPrefix '_' overlapMethodStr '_Overlap.txt'];
    write2DArrayToFile(shotFileName, overlapArr, writeToLogFunctHandle);
    
    % Plot all overlaps.
    figHandle = figure;
    plot(overlapArr);
    xlabel('image pair index');
    ylabel('overlap');
    title([titleStr ' overlaps']);
    axis([1 numel(overlapArr) 1 signalLength]);
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStr '_Overlap.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
    
    % Plot all overlaps (with minimal vertical range).
    figHandle = figure;
    plot(overlapArr);
    xlabel('image pair index');
    ylabel('overlap');
    title([titleStr ' overlaps']);
    axis([1 numel(overlapArr) min(overlapArr) max(overlapArr)]);
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStr '_Overlap_o' ...
        num2str(min(overlapArr)) '-O' num2str(max(overlapArr)) '.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
    
    % Plot the minimal relative differences.
    figHandle = figure;
    plot(minDiffArr);
    xlabel('image pair index');
    ylabel('min relative difference');
    title([titleStr ' relative differences']);
    axis([1 numel(minDiffArr) min(minDiffArr) max(minDiffArr)]);
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStr '_RelDiff_o' ...
        num2str(min(overlapArr)) '-O' num2str(max(overlapArr)) '.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
    
    % Build a histogram of the overlaps with as many bins as there are
    % possible overlaps.
    figHandle = figure;
    hist(overlapArr, signalLength);
    xlabel('overlap');
    ylabel('number of occurrences');
    title([titleStr ' overlaps distribution']);
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStr '_OverlapHist_o' ...
        num2str(min(overlapArr)) '-O' num2str(max(overlapArr)) '.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
end

for k = 1:(numel(overlapMethodStrCellArr) - 1)
    % Build a histogram of the changes in the overlaps computed using two
    % different methods.
    figHandle = figure;
    changeArr = overlapArrCellArr{k + 1} - overlapArrCellArr{k};
    hist(changeArr, min(changeArr):max(changeArr));
    xlabel('difference');
    ylabel('number of occurrences');
    title([titleStrCellArr{k + 1} ' and ' titleStrCellArr{k} ' overlaps differences distribution']);
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStrCellArr{k + 1} '-' ...
        overlapMethodStrCellArr{k} '_OverlapChange.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
end


for k = 1:numel(signalToShowIndArr)
    % Plot two consecutive signals and their calibrated versions.
    figHandle = figure;
    firstInd = signalLength - overlapArr(signalToShowIndArr(k)) + 1;
    lastInd = signalLength - overlapArr(signalToShowIndArr(k)) + signalLength;
    plot((1:signalLength), signalsToShowArr(:, 2*k - 1), 'b', ...
        (firstInd:lastInd), signalsToShowArr(:, 2*k), 'b', ...
        ((leftSamplesToIgnore + 1):(signalLength - rightSamplesToIgnore)), calibSignalsArr(:, signalToShowIndArr(k)), 'r', ...
        ((leftSamplesToIgnore + firstInd):(lastInd - rightSamplesToIgnore)), calibSignalsArr(:, signalToShowIndArr(k) + 1), 'r');
    xlabel('sample index');
    ylabel('amplitude');
    title('Original signals in blue, calibrated signals in red');
    axis tight;
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [commonPrefix '_' overlapMethodStr '_OrigAndCalibPair' ...
        num2str(signalToShowIndArr(k) + 1) '.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
end

return;
% end of the function "visualizeOverlaps"
